package cn.com.service.impl.hr;

import static cn.com.support.message.MessageCodeEnum.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import cn.com.commons.Paginator;
import cn.com.dal.dao.hr.UserDAO;
import cn.com.dal.dao.ref.RefUserRoleDAO;
import cn.com.dal.dataobject.hr.UserDO;
import cn.com.dal.dataobject.ref.RefUserRoleDO;
import cn.com.service.hr.UserService;
import cn.com.support.context.UserContext;
import cn.com.support.message.MessageResult;
import cn.com.support.utils.JacksonUtil;

/**
 * 系统设置，用户管理SERVICE实现类
 * @author Zoe
 */
@Service
public class UserServiceImpl implements UserService {

	private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);

	@Autowired
	private UserDAO<UserDO> userDAO;
	@Autowired
	private RefUserRoleDAO<RefUserRoleDO> userRoleDAO;

	@Override
	public <C> Paginator<C, List<UserDO>> selectByPage(
			Paginator<C, List<UserDO>> paginator) {
		Paginator<C, List<UserDO>> result = null;
		try {
			result = userDAO.selectForPage(paginator);
		} catch (Exception e) {
			logger.error(
					String.format(ERROR_SELECT.descript() + ":[%s]",
							paginator.getCondition()), e);
		}
		//return json string
		return result;
	}

	@Override
	public MessageResult<Long> insert(UserDO userDO) {
		MessageResult<Long> result =  new MessageResult<Long>(false, null, ERROR_INSERT);
		try {
			Long id = userDAO.insert(userDO);
			if (id != null && id > 0) {
				result = new MessageResult<Long>(true, id, INFO_SUCCEED);
			}
		} catch (Exception e) {
			logger.error(String.format(ERROR_INSERT.descript() + ":[%s]", userDO), e);
		}
		return result;
	}

	@Transactional
	@Override
	public MessageResult<Integer> updateById(UserDO userDO) {
		MessageResult<Integer> result =  new MessageResult<Integer>(false, null, ERROR_UPDATE);
		RefUserRoleDO userRoleDO = null;
		try {
			Integer id = userDAO.updateById(userDO);
			if (id != null && id > 0) {
				result = new MessageResult<Integer>(true, id, INFO_SUCCEED);
			}
			String[] roleIds = userDO.getRoleIds();
			roleIds = (null==roleIds?new String[0]:roleIds);
			Long userId = userDO.getId();
			userRoleDO = new RefUserRoleDO();
			userRoleDO.setUserId(userId);
			List<RefUserRoleDO> userRoleLst = userRoleDAO.selectList(userRoleDO);
			Map<String, Object> newIdMap = JacksonUtil.array2Map(roleIds);
			Map<String, Object> oldIdMap = new HashMap<String, Object>();
			//移除不在修改列表中的用户-角色关系
			Long roleId = null;
			for(RefUserRoleDO userRole : userRoleLst){
				roleId = userRole.getRoleId();
				oldIdMap.put(roleId+"", roleId);
				if(!newIdMap.containsKey(roleId)){
					userRoleDAO.deleteById(userRole.getId());
				}
			}
			//增加修改列表中新增的用户-角色关系
			for(String roleIdStr : roleIds){
				roleId = Long.parseLong(roleIdStr.trim());
				if(!oldIdMap.containsKey(roleId)){
					userRoleDO = new RefUserRoleDO();
					userRoleDO.setUserId(userId);
					userRoleDO.setRoleId(roleId);
					userRoleDO.setCreator(UserContext.getUsername());
					userRoleDAO.insert(userRoleDO);
				}
			}
		} catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			logger.error(String.format(ERROR_UPDATE.descript() + ":[%s]", userDO), e);
		}
		return result;
	}

	@Transactional
	@Override
	public MessageResult<Integer> deleteById(List<String> idLst) {
		MessageResult<Integer> result =  new MessageResult<Integer>(true, null, INFO_SUCCEED);
		Integer opId = null;
		UserDO userDO = null;
		try {
			for(String id : idLst){
				userDO = new UserDO();
				userDO.setId(Long.parseLong(id));
				//update用户账号为失效
				userDO.setStatus((byte)4);
				opId = userDAO.updateById(userDO);
				if (opId == null || opId <= 0) {
					result = new MessageResult<Integer>(false, opId, ERROR_DELETE);
					break;
				}
			}
		} catch (Exception e) {
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
			logger.error(String.format(ERROR_DELETE.descript() + ":[%s]", idLst), e);
		}
		return result;
	}

	@Override
	public List<UserDO> selectList(UserDO userDO) {
		List<UserDO> result = null;
		try {
			result = userDAO.selectList(userDO);
		} catch (Exception e) {
			logger.error(
					String.format(ERROR_SELECT.descript() + ":[%s]"), e);
		}
		return result;
	}

	@Override
	public UserDO selectById(Long id) {
		UserDO userDO = null;
		try {
			userDO = userDAO.selectById(id);
		} catch (Exception e) {
			logger.error(
					String.format(ERROR_SELECT.descript() + ":[%s]"), e);
		}
		return userDO;
	}

	@Override
	public List<UserDO> selectListByRole(Map<Object, Object> params) {
		List<UserDO> result = null;
		try {
			result = userDAO.selectListByRole(params);
		} catch (Exception e) {
			logger.error(
					String.format(ERROR_SELECT.descript() + ":[%s]"), e);
		}
		return result;
	}

}
